Welcome back. What if we really want to control the sort order?
Specifying how to break ties,
on the primary property we're using for sorting?
The answer is that, we take advantages of Python's built-in sort order for tuples.
Take a look at this code,
I have a list containing five tuples.
Each tuple has three items in it.
The first tuple has eight, three,
and two, the second tuple has C,
one, and four, and so on.
On line six, I'm going to sort those tuples.
So we're still going to get a list of five tuples,
and then we're just going to print each of them, with an iteration.
What order do you think, they're going to come out in?
Is it just going to do them in
the original order because it doesn't know how to sort tuples?
Is it going to put all of the As first?
So we'll get this one,
and then this one,
and then the B,
and then the two Cs.
Is it going to do some random order?
What's it going to do? Well let's see.
What it's going to do, is put the As first,
and then, the Bs and then the Cs.
So when you sort tuples,
you're really sorting by the first element in those tuples. But there's more.
We have a built-in tie-breaking mechanism, with tuples sorting.
Here, the first values,
were both A, so it went on to the second value,
and two comes before three.
There was only one B, so there was no tie-breaking that needed to happen.
But between the two Cs,
those are equal, so it goes on to the second element.
If those are equal,
it goes on to compare the third elements.
It would even do fourth and fifth as many,
as you had elements in the tuples.
So, when it compares two tuples,
it first compares their first elements.
If one of them is smaller than that whole tuple is smaller,
but if they're equal, it goes on to compare the second elements of the tuples,
and then the third elements and so on.
So that's going to turn out to be useful for us,
when we try to control a sort order for breaking ties,
even when we're not sorting things that are tuples.
Suppose we had really duplicate items,
so we had another A, three, two.
It's exactly the same as the first element.
In that case, it's just going to put both of them in there, one after the other.
So we've got both of the A,
three, two is showing up.
Is never going to collapse them,
if you have six elements to start with and you sort the list,
you're always going to end up with six elements at
the end even if two of them are identical.
All right, so that's sorting tuples.
We're going to take advantage of the Python sort order for tuples,
in order to be able to specify fine-grained control,
on our sort orders for other things,
using tuples, to create a tie-breaking mechanism.
The way we're going to make this tie-breaking mechanism is that,
we're going to make our key function.
As always take one item as input and it's supposed to
return a property of the item that instead of returning one property of the item,
we're going to return a tuple,
containing two properties of the item.
So here's an example.
We've got a list of fruit names,
and we're going to sort them,and the property that we're going to use to sort them,
is defined by this Lambda expression.
It takes as its input one fruit name,
and it returns as its output, a property,
but in this case it's two properties, as a tuple.
The first one is the length of the fruit name,
how long is the word,
and the other is the fruit name itself.
So this is going to produce for peach,
a tuple five comma peach.
For Kiwi, it's going to produce four comma kiwi.
Remember this idea that the key function is sort of,
producing a post-it note that's associated with the item.
So peach has associated with it,
this tuple, and kiwi has associated with it this tuple.
When sorted it's going to decide what order they should go in,
it's sorting them based on these post-it notes, these tuples.
So, for kiwi is going to go before five peach,
because the tuple ordering says,
"Look at the first element of the tuple first".
However, when it comes along,
and sees four comma pair,
it's going to have a tie,
when it compares four with four,
and it's going to then use alphabetic ordering,
as the secondary sort order to break the ties.
So we'll get as our output.
We get the four-letter fruits first; kiwi and pear,
and then the five letter fruits; apple, mango,
and peach, and those are in alphabetic order.
Apple before mango, m before p, mango before peach.
What if we want to have the long words first?
This is just our standard mechanism,
with the sorted function.
We can add the reverse equals True parameter,
and now we'll get blueberry,
to show up first.
That's all fine, except,
it's completely reversed the sort order from what we had before.
So now we have,
peach before mango before apple.
Those are all the five letter words and we now have them in
reverse alphabetic order in addition to reversing the long words to short words.
What if, we wanted to have longest words first,
but break ties, with alphabetic order rather than reverse alphabetical order?
This starts to get pretty tricky.
One solution that's available to us is a little trick.
Instead of using reverse equals true to reverse our sort order,
which will make it so that we reverse both the primary and the secondary property,
I'm going to try to just reverse the primary property.
There is a trick I can use for numeric properties,
like the length of the fruit name.
If I just make all of them be negative values,
so blueberry is now going to be minus nine,
and kiwi is going to be minus four,
minus nine is less than minus four,
and so I'm going to get the longer ones to come first.
But I haven't reversed everything,
so my secondary sort order is still going to be from lowest to highest,
which will be alphabetic.
So I still got blueberry first,
but I now have apple before mango before peach in alphabetic order.
That trick only works if we have a numeric property.
If you had two alphabetic properties and you wanted to do reverse on one,
and not on the other,
it would be harder and I don't have an easy solution for you.
So summarizing.
If you want to specify a tie-breaking property,
have your key function return a tuple.
Like key functions everywhere,
they always take one item from the sequence as input,
but now it's going to return a tuple,
where the first element of the tuple is the primary property to sort by,
the next element is the secondary property to sort by,
and you could even have more elements in the tuple.
We also saw that if you just want to reverse
order for one of the properties but not the others,
instead of using reverse equals true,
you can make the key function return negative of all the numbers. See you next time.